#include "client.h"

#include <pthread.h>

#define THREAD_MAX_SIZE 4

int thread_nums = THREAD_MAX_SIZE;
int cur_thread_num = 0;
pthread_mutex_t thread_mutex = PTHREAD_MUTEX_INITIALIZER; // 互斥锁



void* upload_file(void* arg) {
  struct upload_info *info = (struct upload_info*)arg;
  int new_socket_fd;
  connect_serve(info->ip, info->port, &new_socket_fd);
  if (info->command != ERR && info->command != EXIT) {
    send(new_socket_fd, &info->command, sizeof(int), MSG_NOSIGNAL);
  }
  send(new_socket_fd, &info->command, sizeof(int), MSG_NOSIGNAL);
  put_serverfile(new_socket_fd, info->filename, &info->client_info);
  sleep(30);
  close(new_socket_fd);

  // 线程结束时减少当前线程计数
  pthread_mutex_lock(&thread_mutex);
  cur_thread_num--;
  pthread_mutex_unlock(&thread_mutex);
  return NULL;
}

void* download_file(void* arg) {
  struct download_info *info = (struct download_info*)arg;
  int new_socket_fd;
  connect_serve(info->ip, info->port, &new_socket_fd);
  if (info->command != ERR && info->command != EXIT) {
    send(new_socket_fd, &info->command, sizeof(int), MSG_NOSIGNAL);
  }
  
  send(new_socket_fd, &info->command, sizeof(int), MSG_NOSIGNAL);
  
  get_serverfile(new_socket_fd, info->filename, &info->client_info);
  sleep(30);
  close(new_socket_fd);

  // 线程结束时减少当前线程计数
  pthread_mutex_lock(&thread_mutex);
  cur_thread_num--;
  pthread_mutex_unlock(&thread_mutex);
  return NULL;
}



int main() {
  initLog(1024);

  char *ip;

  char *port;

  ip = parseINI("ip", NULL);

  port = parseINI("port", NULL);

  int ret;
  //ip="192.168.237.128";
  //port="8080";
  //建立连接
  int socket_fd;
  connect_serve(ip, port, &socket_fd);
  //创建结构体并初始化
  struct client_info info;
  struct login_status stat;
  memset(&stat, 0, sizeof(stat));
  int exit_status = 0;

  //while循环执行逻辑
  while (1) {
    printf("\n*******************************这是一条分割线***************************\n");
    memset(&info, 0, sizeof(info));
    if (stat.login == false) {
      printf("检测到您还没有登录\n请选择你的操作:\n");
      printf("0:退出   1:登录   2：注册\n");
      int choose;
      //获取登录的输入
      if (get_choose(&choose) != 0) {
        DEBUG_LOG("获取登录选项失败，用户输入错误\n");
      }
      //执行输入
      if (execute_choose(choose, &stat, &exit_status, &info, socket_fd) != 0) {
        DEBUG_LOG("命令执行出错\n");
      }
      if (exit_status == 1) {
        INFO_LOG("用户退出程序；退出时间：%s\n", get_current_time());
        break;
      }
    } else {
      printf("[剑指]/%s->  ", stat.path);
      if ((get_stdin(&stat, &info)) != 0) {
        DEBUG_LOG("读取命令出错\n");
      }
      switch (info.command) {
        case RM: {
          if (info.command != ERR && info.command != EXIT) {
            send(socket_fd, &info.command, sizeof(int), MSG_NOSIGNAL);
          }
          rmClient(socket_fd, info.protocol, stat.token);
          break;
        }
        case LS: {
          if (info.command != ERR && info.command != EXIT) {
            send(socket_fd, &info.command, sizeof(int), MSG_NOSIGNAL);
          }
          lsClient(socket_fd, info.protocol);
          break;
        }
        case MKDIR: {
          if (info.command != ERR && info.command != EXIT) {
            send(socket_fd, &info.command, sizeof(int), MSG_NOSIGNAL);
          }
          mkdirClient(socket_fd, info.protocol);
          break;
        }
        case PUTS: {
          char filename[100];
          getparama(&info, filename);


          // 检查当前线程数
          pthread_mutex_lock(&thread_mutex);
          if (cur_thread_num >= thread_nums) {
            printf("当前活动线程数已达到最大限制，无法创建新线程。\n");
            pthread_mutex_unlock(&thread_mutex);
            break; // 超过最大线程数，退出
          }
          cur_thread_num++;
          pthread_mutex_unlock(&thread_mutex);

          struct upload_info upload_info = {
              .client_info=info,
              .ip = ip,
              .port = port,
              .command = PUTS,
          };
          strncpy(upload_info.filename, filename, sizeof(upload_info.filename));

          pthread_t upload_thread;
          if (pthread_create(&upload_thread, NULL, upload_file, (void*)&upload_info) != 0) {
            perror("创建上传线程失败");
          }
          pthread_detach(upload_thread); // 不等待线程完成

          // 在线程结束时减少当前线程计数
          pthread_mutex_lock(&thread_mutex);
          cur_thread_num--;
          pthread_mutex_unlock(&thread_mutex);
          usleep(100000);
          break;
        }

        case GETS: {
          char filename[100];
          getparama(&info, filename);

          // 检查当前线程数
          pthread_mutex_lock(&thread_mutex);
          if (cur_thread_num >= thread_nums) {
            printf("当前活动线程数已达到最大限制，无法创建新线程。\n");
            pthread_mutex_unlock(&thread_mutex);
            break; // 超过最大线程数，退出
          }
          cur_thread_num++;
          pthread_mutex_unlock(&thread_mutex);

          struct download_info download_info = {
              .client_info=info,
              .ip = ip,
              .port = port,
              .command = GETS,
          };
          strncpy(download_info.filename, filename, sizeof(download_info.filename));

          pthread_t download_thread;
          if (pthread_create(&download_thread, NULL, download_file, (void*)&download_info) != 0) {
            perror("创建下载线程失败");
          }
          pthread_detach(download_thread); // 不等待线程完成

          // 在线程结束时减少当前线程计数
          pthread_mutex_lock(&thread_mutex);
          cur_thread_num--;
          pthread_mutex_unlock(&thread_mutex);
          usleep(100000);
          break;
        }

        case CD: {
          if (info.command != ERR && info.command != EXIT) {
            send(socket_fd, &info.command, sizeof(int), MSG_NOSIGNAL);
          }
          cdClient(socket_fd, info.protocol, &stat);
          break;
        }
        case PWD: {
          if (info.command != ERR && info.command != EXIT) {
            send(socket_fd, &info.command, sizeof(int), MSG_NOSIGNAL);
          }
          pwdClient(&stat);
          break;
        }
        case LOGOUT:
          if (info.command != ERR && info.command != EXIT) {
            send(socket_fd, &info.command, sizeof(int), MSG_NOSIGNAL);
          }
                  logoutClient(socket_fd, &stat);
                  break;
        case ERR:printf("您的输入格式有问题，请重新输入\n");
          break;
        case EXIT:printf("您选择退出登录\n");
          exit(0);
          break;
        default:break;
      }
    }
  }
  printf("你选择退出，进程结束\n");
}





